# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# Copyright 2018 by Donghao Wang. All Rights Reserved.
# 此脚本为免费脚本，你可以修改和发布任何内容，但请备注我的名字。
#王东浩写于2018.10.9
##########################################################################
from PySide2 import QtWidgets
from PySide2 import QtCore
from PySide2 import QtGui
from shiboken2 import wrapInstance
import pyside2uic
import xml.etree.ElementTree as xml
from cStringIO import StringIO
import maya.cmds as mc
import maya.OpenMayaUI as mui
import maya.mel as mel
import os
import glob
import math
import re
from DH_IKFKSW import DH_PySideUidata
from DH_IKFKSW import xform_func as xf
reload(xf)

filepath = str(os.path.split(os.path.realpath(__file__))[0])
form_class, base_class = DH_PySideUidata.loadUiType(
    filepath + '/ui/DH_IKFK_switcher.ui')


class DH_IKFKSwitcher_tool(base_class, form_class):

    def __init__(self):
        self.window_name = 'DH_IKFKSwitcher_win'
        if mc.window(self.window_name, exists=True):
            mc.deleteUI(self.window_name)
        super(DH_IKFKSwitcher_tool, self).__init__(
            parent=DH_PySideUidata.getMayaWindow())
        self.setupUi(self)
        desktop = QtWidgets.QApplication.desktop().availableGeometry()
        size = self.geometry()
        self.move((desktop.width() - size.width()) / 2,
                  (desktop.height() - size.height()) / 2)
        self.set_proj()

        self.pushButton_HSWIK.clicked.connect(self.handSW_IK)
        self.pushButton_HSWFK.clicked.connect(self.handSW_FK)
        self.pushButton_FSWIK.clicked.connect(self.footSW_IK)
        self.pushButton_FSWFK.clicked.connect(self.footSW_FK)

    def erroroutput(self, errorContent):  # 用来输出错误
        mc.confirmDialog(title=u'error', message=errorContent, button=[u'ok'])

    def set_proj(self):  # 读入所有项目，在这个位置C:\Users\%username%\Documents\maya\2017\scripts\DH_IKFKSW\projects
        proj_dir = mc.internalVar(usd=1).encode('utf-8') + "DH_IKFKSW/projects"
        all_proj = mc.getFileList(filespec="*.swfile", folder=proj_dir)
        items = []
        for _ in all_proj:
            items.append(_.replace(".swfile", ""))
        self.comboBox_proj.addItems(items)

    def readcfg(self):  # 读取配置信息并返回
        script_dir = mc.internalVar(usd=1)
        projname = self.comboBox_proj.currentText()
        if not projname:
            self.erroroutput(u"没有发现项目文件！请确保选择了项目，或者联系绑定生成项目配置。")
            return
        # 配置文件在C:\Users\%username%\Documents\maya\2017\scripts\DH_IKFKSW\projects
        file_path = script_dir + "DH_IKFKSW/projects/" + projname + ".swfile"
        config_content = []
        if os.path.isfile(file_path):
            #print file_path
            config_file = open(file_path.replace("\\","/"), "r")
            config_content = config_file.read().split("%%")  # 配置信息中是用%%连接的，这里要拆开
            config_file.close()
        return config_content  # 将读入的配置信息以列表形式返回

    def left_or_right(self):  # 这个用来判断左右
        if not mc.ls(sl=1):
            self.erroroutput(u"请先选择控制器！")
            return
        selCtrl = mc.ls(sl=1)[0]
        ctrl_name = self.readcfg()  # 读入配置信息并放入ctrl_name
        lf_or_rt = [ctrl_name[17], ctrl_name[18], ctrl_name[19], ctrl_name[20]]
        # print lf_or_rt
        if not selCtrl:
            self.erroroutput(u'请先选择手或腿的控制器再转换！')
            return
        for _ in lf_or_rt:
            if re.search(_, selCtrl):
                return _
        self.erroroutput(u'选择的第一个物体不是手或者脚上的控制器,或者绑定结构和配置文件不同！无法判断左右！')
        return False

    def search_lfRt(self, ctrl):  # 这个用来将字符中的左或者右找出来
        ctrl_name = self.readcfg()  # 读入配置信息并放入ctrl_name
        lf_or_rt = [ctrl_name[17], ctrl_name[18], ctrl_name[19], ctrl_name[20]]
        for _ in lf_or_rt:
            if re.search(_, ctrl):
                return _
        return False

    def handSW_IK(self):
        if not mc.objExists("*:*" + "_for_IK_Tracking"):
            self.erroroutput(u"未发现追踪节点,或者角色不是引用模式！请联系绑定师更新绑定。")
            return
        if not mc.ls(sl=1):
            self.erroroutput(u"请先选择控制器！")
            return
        selCtrl = mc.ls(sl=1)[0].split(":")[0]+":"
        lf_or_rt = self.left_or_right()  # 判断选中的控制器的左右
        #print (u'选中的是'+lf_or_rt)
        ctrl_name = self.readcfg()  # 读入配置信息并放入ctrl_name

        shoulder_tracking_ctrl = selCtrl+ctrl_name[4].replace(self.search_lfRt(
            ctrl_name[4]), lf_or_rt) + "_for_IK_Tracking"  # 这个是FK肩膀控制器下面的追踪器名称
        wrist_tracking_ctrl = selCtrl + ctrl_name[5].replace(self.search_lfRt(
            ctrl_name[5]), lf_or_rt) + "_for_IK_Tracking"  # 这个是FK手腕控制器下面的追踪器名称
        IK_ctrl = selCtrl +  ctrl_name[5].replace(
            self.search_lfRt(ctrl_name[5]), lf_or_rt)  # IK控制器名称
        pole_ctrl = selCtrl +  ctrl_name[4].replace(
            self.search_lfRt(ctrl_name[4]), lf_or_rt)  # 极向量名称
        xf.xformPwsT([IK_ctrl, pole_ctrl], xf.xformQwsT(
            wrist_tracking_ctrl, shoulder_tracking_ctrl))  # 将两个追踪器的位置信息传给IK
        xf.xformPwsRo([IK_ctrl], xf.xformQwsRo(
            wrist_tracking_ctrl))  # 将手腕追踪器的旋转信息传递给IK手控制器
        IKFKBlend = ctrl_name[25]
        IKFKBlend_new = selCtrl + ctrl_name[25]
        #print IKFKBlend_new
        mel.eval(ctrl_name[21].replace(IKFKBlend,IKFKBlend_new).replace(self.search_lfRt(ctrl_name[21]), lf_or_rt))  # 将IKFKBlend打成IK状态
        return True

    def handSW_FK(self):
        lf_or_rt = self.left_or_right()  # 判断选中的控制器的左右
        ctrl_name = self.readcfg()  # 读入配置信息并放入ctrl_name
        if not mc.ls(sl=1):
            self.erroroutput(u"请先选择控制器！")
            return
        selCtrl = mc.ls(sl=1)[0].split(":")[0]+":"
        shoulder_ctrl = selCtrl +  ctrl_name[6].replace(
            self.search_lfRt(ctrl_name[6]), lf_or_rt)  # 这个是FK肩膀控制器名称
        elbow_ctrl = selCtrl +  ctrl_name[7].replace(
            self.search_lfRt(ctrl_name[7]), lf_or_rt)  # 这个是FK肘控制器名称
        wrist_tracking_ctrl = selCtrl +  ctrl_name[8].replace(
            self.search_lfRt(ctrl_name[8]), lf_or_rt)  # 这个是FK手腕控制器名称

        IK_shoulder_jnt = selCtrl +  ctrl_name[1].replace(
            self.search_lfRt(ctrl_name[1]), lf_or_rt)  # IK肩膀骨骼名称
        IK_elbow_jnt = selCtrl +  ctrl_name[2].replace(
            self.search_lfRt(ctrl_name[2]), lf_or_rt)  # IK肘部骨骼名称
        IK_wrist_jnt = selCtrl +  ctrl_name[3].replace(
            self.search_lfRt(ctrl_name[3]), lf_or_rt)  # IK手腕骨骼名称

        xf.xformPwsRo([shoulder_ctrl, elbow_ctrl, wrist_tracking_ctrl], xf.xformQwsRo(
            IK_shoulder_jnt, IK_elbow_jnt, IK_wrist_jnt))  # 将IK骨骼旋转信息传递给FK控制器

        IKFKBlend = ctrl_name[25]
        IKFKBlend_new = selCtrl + ctrl_name[25]
        mel.eval(ctrl_name[22].replace(IKFKBlend,IKFKBlend_new).replace(self.search_lfRt(ctrl_name[22]), lf_or_rt))  # 将IKFKBlend打成FK状态
        return True

    def footSW_IK(self):
        if not mc.objExists("*:*" + "_for_IK_Tracking"):
            self.erroroutput(u"未发现追踪节点,或者角色不是引用模式！请联系绑定师更新绑定.")
            return
        if not mc.ls(sl=1):
            self.erroroutput(u"请先选择控制器！")
            return
        selCtrl = mc.ls(sl=1)[0].split(":")[0]+":"
        lf_or_rt = self.left_or_right()  # 判断选中的控制器的左右
        ctrl_name = self.readcfg()  # 读入配置信息并放入ctrl_name
        shoulder_tracking_ctrl = selCtrl +  ctrl_name[12].replace(self.search_lfRt(
            ctrl_name[12]), lf_or_rt) + "_for_IK_Tracking"  # 这个是FK胯控制器下面的追踪器名称
        wrist_tracking_ctrl = selCtrl +  ctrl_name[13].replace(self.search_lfRt(
            ctrl_name[13]), lf_or_rt) + "_for_IK_Tracking"  # 这个是FK脚控制器下面的追踪器名称
        IK_ctrl = selCtrl +  ctrl_name[13].replace(
            self.search_lfRt(ctrl_name[13]), lf_or_rt)  # IK控制器名称
        pole_ctrl = selCtrl +  ctrl_name[12].replace(
            self.search_lfRt(ctrl_name[12]), lf_or_rt)  # 极向量名称
        xf.xformPwsT([IK_ctrl, pole_ctrl], xf.xformQwsT(
            wrist_tracking_ctrl, shoulder_tracking_ctrl))  # 将两个追踪器的位置信息传给IK
        xf.xformPwsRo([IK_ctrl], xf.xformQwsRo(
            wrist_tracking_ctrl))  # 将脚追踪器的旋转信息传递给IK手控制器
        IKFKBlend = ctrl_name[26]
        IKFKBlend_new = selCtrl + ctrl_name[26]
        mel.eval(ctrl_name[23].replace(IKFKBlend,IKFKBlend_new).replace(self.search_lfRt(ctrl_name[23]), lf_or_rt))  # 将IKFKBlend打成IK状态
        return True

    def footSW_FK(self):
        lf_or_rt = self.left_or_right()  # 判断选中的控制器的左右
        ctrl_name = self.readcfg()  # 读入配置信息并放入ctrl_name
        if not mc.ls(sl=1):
            self.erroroutput(u"请先选择控制器！")
            return
        selCtrl = mc.ls(sl=1)[0].split(":")[0]+":"
        shoulder_ctrl = selCtrl +  ctrl_name[14].replace(
            self.search_lfRt(ctrl_name[14]), lf_or_rt)  # 这个是FK胯控制器名称
        elbow_ctrl = selCtrl +  ctrl_name[15].replace(
            self.search_lfRt(ctrl_name[15]), lf_or_rt)  # 这个是FK膝盖控制器名称
        wrist_tracking_ctrl = selCtrl +  ctrl_name[16].replace(
            self.search_lfRt(ctrl_name[16]), lf_or_rt)  # 这个是FK脚控制器名称

        IK_shoulder_jnt = selCtrl +  ctrl_name[9].replace(
            self.search_lfRt(ctrl_name[9]), lf_or_rt)  # IK胯骨骼名称
        IK_elbow_jnt = selCtrl +  ctrl_name[10].replace(
            self.search_lfRt(ctrl_name[10]), lf_or_rt)  # IK膝盖骨骼名称
        IK_wrist_jnt = selCtrl +  ctrl_name[11].replace(
            self.search_lfRt(ctrl_name[11]), lf_or_rt)  # IK脚骨骼名称

        xf.xformPwsRo([shoulder_ctrl, elbow_ctrl, wrist_tracking_ctrl], xf.xformQwsRo(
            IK_shoulder_jnt, IK_elbow_jnt, IK_wrist_jnt))  # 将IK骨骼旋转信息传递给FK控制器
        IKFKBlend = ctrl_name[26]
        IKFKBlend_new = selCtrl + ctrl_name[26]
        mel.eval(ctrl_name[24].replace(IKFKBlend,IKFKBlend_new).replace(self.search_lfRt(ctrl_name[24]), lf_or_rt))  # 将IKFKBlend打成FK状态
        return True


if __name__ == "__main__":
    DH_IKFKSwitcher_tool().show()
